#pragma once

#include <iostream>


template<typename T, int desiredCapacity=10>
class Stack
{
public:
	Stack();
	~Stack();

	void ShowData();
	int Capacity() const;
	int Size() const;

	void Push(T element);
	bool IsEmpty() const;
	T Pop();
private:
	int capacity;
	int top; // 栈顶索引
	T* data;
};

template <typename T, int desiredCapacity>
Stack<T, desiredCapacity>::Stack():
capacity(desiredCapacity),
top(-1),
data(new T[capacity])
{
}

template <typename T, int desiredCapacity>
Stack<T, desiredCapacity>::~Stack()
{
	delete[] data;
}

template <typename T, int desiredCapacity>
void Stack<T, desiredCapacity>::ShowData()
{
	std::cout << "Show Stack: \n";
	std::cout << "Capacity: " << capacity << "\n";
	std::cout << "Size: " << top + 1 << "\n";

	for (int i = top; i >= 0; --i)
	{
		std::cout << "| " << data[i] << " |\n"; 
	}

	std::cout << std::endl;
}

template <typename T, int desiredCapacity>
int Stack<T, desiredCapacity>::Capacity() const
{
	return capacity;
}

template <typename T, int desiredCapacity>
int Stack<T, desiredCapacity>::Size() const
{
	return top;
}

template <typename T, int desiredCapacity>
void Stack<T, desiredCapacity>::Push(T element)
{
	if (top == capacity)
		return;

	data[++top] = element;
}

template <typename T, int desiredCapacity>
bool Stack<T, desiredCapacity>::IsEmpty() const
{
	return top <= 0;
} 

template <typename T, int desiredCapacity>
T Stack<T, desiredCapacity>::Pop()
{
	return data[top--];
}
